[IA64] Self IO EMUlator - tools part
authorAlex Williamson <alex.williamson@hp.com>
Tue, 19 Feb 2008 15:12:28 +0000 (08:12 -0700)
committerAlex Williamson <alex.williamson@hp.com>
Tue, 19 Feb 2008 15:12:28 +0000 (08:12 -0700)
Signed-off-by: Tristan Gingold <tgingold@free.fr>
tools/libxc/ia64/Makefile
tools/libxc/ia64/xc_dom_ia64_util.h
tools/libxc/ia64/xc_ia64_dom_fwloader.c [new file with mode: 0644]
tools/libxc/xc_dom_ia64.c

index 4fd4fbbe8649133b597ca2d92049f2fb602632e4..cc1563330513e6eb662236cd55012e71a9a96d94 100644 (file)
@@ -8,6 +8,8 @@ GUEST_SRCS-y += ia64/xc_ia64_linux_restore.c
 GUEST_SRCS-y += ia64/xc_dom_ia64_util.c
 GUEST_SRCS-y += ia64/dom_fw_acpi.c
 
+GUEST_SRCS-y += ia64/xc_ia64_dom_fwloader.c
+
 DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S
 endif
 DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE))
index 66dfa41f016589bcb20c599054eb3db5008f2d22..61bfa61830fb4c651a38129a0c4c9b6adf5b8a89 100644 (file)
@@ -16,4 +16,11 @@ xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm,
 #define efi_systable_init_dom0(tables) assert(0)
 #define complete_dom0_memmap(d, tables) ({assert(0);0;})
 
+/* Defined in xc_dom_ia64.c  */
+extern int start_info_ia64(struct xc_dom_image *dom);
+extern int shared_info_ia64(struct xc_dom_image *dom, void *ptr);
+
+#define FW_MEM_BASE 0xff000000UL
+#define FW_MEM_SIZE 0x01000000UL
+
 #endif /* XC_IA64_DOM_IA64_UTIL_H */
diff --git a/tools/libxc/ia64/xc_ia64_dom_fwloader.c b/tools/libxc/ia64/xc_ia64_dom_fwloader.c
new file mode 100644 (file)
index 0000000..4f3b25a
--- /dev/null
@@ -0,0 +1,124 @@
+#include <stdlib.h>
+#include <inttypes.h>
+#include <asm/kregs.h>
+
+#include <xen/xen.h>
+#include <xen/foreign/ia64.h>
+#include <xen/io/protocols.h>
+
+#include "xg_private.h"
+#include "xc_dom.h"
+
+#include "ia64/xc_dom_ia64_util.h"
+
+static const char fw_magic[16] = {'X', 'e', 'n', '-',
+                                  'i', 'a', '6', '4',
+                                  '-', 'f', 'w', 0,
+                                  0, 0, 0, 0};
+#define FW_LOAD 0xff800000UL
+#define FW_SIZE (8 * 1024 * 1024)
+
+static int xc_dom_probe_fw_kernel(struct xc_dom_image *dom)
+{
+    if (dom->kernel_size != FW_SIZE)
+        return -EINVAL;
+    if (memcmp (dom->kernel_blob, fw_magic, sizeof (fw_magic)))
+        return -EINVAL;
+    return 0;
+}
+
+static int xc_dom_parse_fw_kernel(struct xc_dom_image *dom)
+{
+    dom->kernel_seg.vstart = FW_LOAD;
+    dom->kernel_seg.vend = FW_LOAD + FW_SIZE;
+    dom->parms.virt_base = FW_MEM_BASE;
+    dom->parms.virt_entry = FW_LOAD + sizeof (fw_magic);
+    dom->ramdisk_blob = NULL; /* No ramdisk yet.  */
+    dom->guest_type = "hvm-3.0-ia64-sioemu";
+    return 0;
+}
+
+static int xc_dom_load_fw_kernel(struct xc_dom_image *dom)
+{
+    char *dest;
+    unsigned long i;
+
+    dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
+    memcpy(dest, dom->kernel_blob, FW_SIZE);
+
+    /* Synchronize cache.  */
+    for (i = 0; i < FW_SIZE; i += 32)
+        asm volatile ("fc.i %0" :: "r"(dest + i) : "memory");
+
+    return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int alloc_magic_pages(struct xc_dom_image *dom)
+{
+    /* allocate special pages */
+    dom->console_pfn = 0;
+    dom->xenstore_pfn = 1;
+    dom->start_info_pfn = 2;
+    return 0;
+}
+
+extern unsigned long xc_ia64_fpsr_default(void);
+
+static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
+{
+    vcpu_guest_context_ia64_t *ctxt = ptr;
+
+    xc_dom_printf("%s: called\n", __FUNCTION__);
+
+    /* clear everything */
+    memset(ctxt, 0, sizeof(*ctxt));
+
+    ctxt->flags = 0;
+    ctxt->regs.ip = dom->parms.virt_entry;
+#ifdef __ia64__                        /* FIXME */
+    ctxt->regs.ar.fpsr = xc_ia64_fpsr_default();
+#endif
+    ctxt->regs.cr.isr = 1UL << 63;
+    ctxt->regs.psr = IA64_PSR_AC | IA64_PSR_BN;
+    ctxt->regs.cr.dcr = 0;
+    ctxt->regs.cr.pta = 15 << 2;
+
+    return 0;
+}
+
+static struct xc_dom_arch xc_dom_arch_ia64_fw = {
+    .guest_type = "hvm-3.0-ia64-sioemu",
+    .native_protocol = XEN_IO_PROTO_ABI_IA64,
+    .page_shift = PAGE_SHIFT_IA64,
+    .alloc_magic_pages = alloc_magic_pages,
+    .start_info = start_info_ia64,
+    .shared_info = shared_info_ia64,
+    .vcpu = vcpu_ia64,
+};
+
+/* ------------------------------------------------------------------------ */
+
+static struct xc_dom_loader fw_loader = {
+    .name = "xen-ia64-fw",
+    .probe = xc_dom_probe_fw_kernel,
+    .parser = xc_dom_parse_fw_kernel,
+    .loader = xc_dom_load_fw_kernel,
+};
+
+static void __init register_fwloader(void)
+{
+    xc_dom_register_arch_hooks(&xc_dom_arch_ia64_fw);
+    xc_dom_register_loader(&fw_loader);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index fa2c9e61f7dc2bc2f33aaf8d0c9874c5a0c4244b..7610aa1d73b8647d624045700db30f7b0e488d0e 100644 (file)
@@ -37,7 +37,7 @@ static int alloc_magic_pages(struct xc_dom_image *dom)
     return 0;
 }
 
-static int start_info_ia64(struct xc_dom_image *dom)
+int start_info_ia64(struct xc_dom_image *dom)
 {
     start_info_ia64_t *start_info =
         xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
@@ -79,7 +79,7 @@ static int start_info_ia64(struct xc_dom_image *dom)
     return 0;
 }
 
-static int shared_info_ia64(struct xc_dom_image *dom, void *ptr)
+int shared_info_ia64(struct xc_dom_image *dom, void *ptr)
 {
     shared_info_ia64_t *shared_info = ptr;
     int i;
@@ -153,15 +153,27 @@ int arch_setup_meminit(struct xc_dom_image *dom)
 {
     xen_pfn_t pfn;
     int rc;
+    unsigned long start;
+    unsigned long nbr;
 
     /* setup initial p2m */
-    dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages);
-    for ( pfn = 0; pfn < dom->total_pages; pfn++ )
-        dom->p2m_host[pfn] = pfn;
+    if (dom->guest_type && strcmp(dom->guest_type,
+                                  "hvm-3.0-ia64-sioemu") == 0) {
+        start = FW_MEM_BASE >> PAGE_SHIFT_IA64;
+        nbr = FW_MEM_SIZE >> PAGE_SHIFT_IA64;
+    } else {
+        start = 0;
+        nbr = dom->total_pages;
+    }
+
+    /* setup initial p2m */
+    dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nbr);
+    for ( pfn = 0; pfn < nbr; pfn++ )
+        dom->p2m_host[pfn] = start + pfn;
 
     /* allocate guest memory */
     rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
-                                           dom->total_pages, 0, 0,
+                                           nbr, 0, 0,
                                            dom->p2m_host);
     return rc;
 }
@@ -232,7 +244,20 @@ int arch_setup_bootearly(struct xc_dom_image *dom)
     DECLARE_DOMCTL;
     int rc;
 
-    xc_dom_printf("%s: setup firmware\n", __FUNCTION__);
+    xc_dom_printf("%s: setup firmware for %s\n", __FUNCTION__, dom->guest_type);
+
+    if (dom->guest_type && strcmp(dom->guest_type,
+                                  "hvm-3.0-ia64-sioemu") == 0) {
+        memset(&domctl, 0, sizeof(domctl));
+        domctl.u.arch_setup.flags = XEN_DOMAINSETUP_sioemu_guest;
+        domctl.u.arch_setup.bp = 0;
+        domctl.u.arch_setup.maxmem = 0;
+        domctl.cmd = XEN_DOMCTL_arch_setup;
+        domctl.domain = dom->guest_domid;
+        rc = xc_domctl(dom->guest_xc, &domctl);
+        xc_dom_printf("%s: hvm-3.0-ia64-sioemu: %d\n", __FUNCTION__, rc);
+        return rc;
+    }
 
     rc = ia64_setup_memmap(dom);
     if (rc)